package com.apestech.framework.json;

import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;

import com.apestech.framework.dictionary.modul.ImportedKey;
import com.apestech.framework.dictionary.modul.PrimaryKey;
import com.apestech.framework.dictionary.modul.Table;
import com.apestech.framework.util.StringUtil;
import com.fasterxml.jackson.core.JsonParser.Feature;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.apache.poi.ss.formula.functions.T;


/**
 * 自封装的JSONObect, JSONArray类，主体为java.util.Map, java.util.List结合FastJSON常用方法（部分），字串和转象之间的转换采用jackson
 * 该单元只支持JAVABEAN,String,Map,List转成JSONObject,JSONArray
 * 指针类的可用SqlResultSet下的方法去转义 
 * //允许出现特殊字符和转义符
   mapper.configure(Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true) ;
   //允许出现单引号
   mapper.configure(Feature.ALLOW_SINGLE_QUOTES, true) ;
 * @author hupo
 *
 */
public class
JSON extends StringUtil {
	
	protected static ObjectMapper objectMapper=new ObjectMapper().disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
	
	private static <T> Object readValue(String src, Class<T> valueType) throws Exception{
		try {
			objectMapper.configure(Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);
			return objectMapper.readValue(src,valueType);
		} catch (IOException e) {
			throw new Exception(e.getMessage());
		}
	}
	
	private static <T> Object readValue(byte[] src, Class<T> valueType) throws Exception{
		try {
			objectMapper.configure(Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);
			return objectMapper.readValue(src, valueType);
		} catch (IOException e) {
			throw new Exception(e.getMessage());
		}
	}
	
	public static byte[] toJSONByte(Object object) throws Exception{
		try {
			SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
			objectMapper.setDateFormat(fmt);  
			return objectMapper.writeValueAsBytes(object);
		} catch (JsonProcessingException e) {
			throw new Exception(e.getMessage());
		}  
	}
	
	public static void toValue(OutputStream out, Object value) throws Exception{
		try {
			SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
			objectMapper.setDateFormat(fmt);  
			objectMapper.writeValue(out, value);
		} catch (JsonProcessingException e) {
			throw new Exception(e.getMessage());
		}  
	}
	
	public static String toJSONString(Object object) throws Exception{
		try {
			if(object==null) return null;
			return objectMapper.writeValueAsString(object);
		} catch (JsonProcessingException e) {
			throw new Exception(e.getMessage());
		}  
	}
	
	public static String toJSONStringWithDateFormat(Object object) throws Exception{
		try {
			SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
			objectMapper.setDateFormat(fmt);  
			return objectMapper.writeValueAsString(object);
		} catch (JsonProcessingException e) {
			throw new Exception(e.getMessage());
		}  
	}

	public static Object toBean(byte[] src, Class valueType) throws Exception {
		try {
			return readValue(src, valueType);
		} catch (JsonProcessingException e) {
			throw new Exception(e.getMessage());
		}
	}

	public static Object toBean(Object object, Class valueType) throws Exception{
		try {
			byte[] src=toJSONByte(object);
			return readValue(src, valueType);
		} catch (JsonProcessingException e) {
			throw new Exception(e.getMessage());
		}
	}

	public static Object toBean(String src, Class valueType) throws Exception{
		try {
			return readValue(src, valueType);
		} catch (JsonProcessingException e) {
			throw new Exception(e.getMessage());
		}
	}

	public static JSONObject toJSON(Object object) throws Exception{
		try {
			byte[] src=toJSONByte(object);
			return (JSONObject) readValue(src, JSONObject.class);
		} catch (JsonProcessingException e) {
			throw new Exception(e.getMessage());
		}  
	}
	
	public static JSONObject toJSON(String src) throws Exception{
		try {
			return (JSONObject) readValue(src, JSONObject.class);
		} catch (JsonProcessingException e) {
			throw new Exception(e.getMessage());
		}
	}
	
	public static JSONObject toJSON(byte[] src) throws Exception{
		try {
			return (JSONObject) readValue(src, JSONObject.class);
		} catch (JsonProcessingException e) {
			throw new Exception(e.getMessage());
		}
	}
	
	public static JSONArray toJSONArray(Object object) throws Exception{
		byte[] src=toJSONByte(object);
		return toJSONArray(src);
	}
	
	public static JSONArray toJSONArray(String src) throws Exception{
		if(!leftStr(src,1).equals("[")){
			src="["+src+"]";
		}
		return (JSONArray) readValue(src, JSONArray.class);
	}
	
	public static JSONArray toJSONArray(byte[] src) throws Exception{
		return (JSONArray) readValue(src, JSONArray.class);
	}
	
	public static <T> T parse(Object object, Class<T> valueType) throws Exception{
		try {
			if(valueType==JSONObject.class){
				return (T) toJSON(object);
			} else if(valueType==JSONArray.class){
				return (T) toJSONArray(object);
			} else {
				byte[] src=toJSONByte(object);
				return objectMapper.readValue(src,valueType);
			}
		} catch (JsonProcessingException e) {
			throw new Exception(e.getMessage());
		}  
	}
	
}
